
#include "input.h"
#include "sdlmisc.h"

using namespace WtfEngine;


/**
 * Translates an SDL key event to our internal unicode format.
 **/
bool __TranslateKey(SDL_Event& event)
{
	/*if((event.key.keysym.sym == SDLK_BACKSPACE)
		   || (event.key.keysym.sym == SDLK_RETURN)
		   || ((event.key.keysym.sym >= SDLK_SPACE)
		   && (event.key.keysym.sym < SDLK_DELETE))){*/
	if(event.key.keysym.unicode) {
		// Valid unicode
		return true;
	} else {
		if(SDLK_a <= event.key.keysym.sym && event.key.keysym.sym <= SDLK_z) {
			event.key.keysym.unicode = 'a' + (event.key.keysym.sym - SDLK_a);
		} else switch(event.key.keysym.sym){
			case SDLK_TAB:
				event.key.keysym.unicode = '\t';
				break;
			case SDLK_UP:
				event.key.keysym.unicode = InputKey::UP;
				break;
			case SDLK_DOWN:
				event.key.keysym.unicode = InputKey::DOWN;
				break;
			case SDLK_LEFT:
				event.key.keysym.unicode = InputKey::LEFT;
				break;
			case SDLK_RIGHT:
				event.key.keysym.unicode = InputKey::RIGHT;
				break;
			case SDLK_SPACE:
				event.key.keysym.unicode = ' ';
				break;
			default:
				return false;
		};
		
		return true;
	};
};

void InputHandler::Run()
{
	// check for SDL events
	SDL_Event event;
	while (SDL_PollEvent(&event)) 
	{
		switch (event.type) 
		{
			case SDL_KEYDOWN:
				if(__TranslateKey(event)){
					
					Kernel::GetInstance().ProcessEvent(
										new KeyEvent(InputKey(event.key.keysym)));
					
					Kernel::GetInstance().ProcessEvent(
										new KeyDownEvent(InputKey(event.key.keysym)));
				};
				
				break;
			
			case SDL_KEYUP:
				if(__TranslateKey(event)) {
				
					Kernel::GetInstance().ProcessEvent(
										new KeyUpEvent(InputKey(event.key.keysym)));
				};
				
				break;
			
			case SDL_MOUSEMOTION:
				Kernel::GetInstance().ProcessEvent(
					new MouseMoveEvent(
						((SDL_MouseMotionEvent *)&event)->x,
						((SDL_MouseMotionEvent *)&event)->y,
						((SDL_MouseMotionEvent *)&event)->xrel,
						((SDL_MouseMotionEvent *)&event)->yrel));
				break;

			case SDL_MOUSEBUTTONDOWN:
				Kernel::GetInstance().ProcessEvent(
					new MouseDownEvent(
						event.button.x,
	  					event.button.y,
						(tMouseButton)event.button.button
					));
				break;

			case SDL_MOUSEBUTTONUP:
				Kernel::GetInstance().ProcessEvent(
					new MouseUpEvent(
						event.button.x,
	  					event.button.y,
						(tMouseButton)event.button.button
					));
				break;
			
			case SDL_VIDEORESIZE:
			{
				WtfGraphics::tGraphicsMode::tCacheRef rGfxMode("v_graphicsMode");
				WtfGraphics::GraphicsMode mode(rGfxMode->Value);
				mode.Resolution = iVector2D( event.resize.w, event.resize.h );
				*rGfxMode = mode;
				break;
			}
			case SDL_QUIT:
				Kernel::GetInstance().SetSystemStatus(Kernel::SYSTEM_EXITING);

			default:
				break;
		}
	}
};

void InputHandler::CaptureAllInput(bool b) {
	if(b) {
		SDL_WM_GrabInput(SDL_GRAB_ON);
		SDL_ShowCursor(SDL_DISABLE);
	} else {
		SDL_WM_GrabInput(SDL_GRAB_OFF);
		SDL_ShowCursor(SDL_ENABLE);
	};
};

void InputHandler::EnterGameMode() {
	SDL_EnableKeyRepeat(0, 0);
};

void InputHandler::EnterGuiMode() {
	SDL_WM_GrabInput(SDL_GRAB_OFF);
	SDL_ShowCursor(SDL_ENABLE);
	SDL_EnableKeyRepeat(300, 50);
};

iVector2D InputHandler::GetMousePosition() const {
	iVector2D vPos;
	SDL_GetMouseState(&vPos[0], &vPos[1]);
	return vPos;
};

bool InputHandler::IsKeyPressed(const WtfEngine::InputKey &key) const {
	// TODO: translate unicode back to SDLK
	return false;
};

